# Virtual Router Simulator 
#
# Copyright (C) 2009-2010 VRSim Project
# Author: Choonho Son <choonho@kt.com>
# URL: <http://vrsim.googlecode.com>
# For license information, see LICENSE.TXT
#
import math

import VRSim.Globals as globals
from VRSim.Node.XML import XML
from PyQt4 import QtGui,  QtCore
from VRSim.Utils import debug,  splash,  message

class AbstractEdge(QtGui.QGraphicsPathItem, QtCore.QObject,  XML):
    def __init__(self,  type,  sourceNode,  sourceIf,  destNode,  destIf,  Fake = False):
        
        QtGui.QGraphicsPathItem.__init__(self)
        
        # Event
        self.setAcceptsHoverEvents(True)
        
        # init XML
        XML.__init__(self, 'Link')
        
        self.type = type
        self.typeName = self.getTypeName()
        self.typeName2 = ""
        self.pointSize = 10
        self.penWidth = 2.0
        
        self.srcCollisionOffset = 0.0
        self.dstCollisionOffset = 0.0
        
        self.source = sourceNode
        self.dest = destNode
        self.fake = Fake
        self.labelSrcIf = sourceIf
        self.labelDstIf = destIf
        self.delay = "1.0"
        if not self.fake:

            #self.source.setCustomToolTip()
            #self.dest.setCustomToolTip()
    
            self.srcIf = sourceIf
            self.srcIfPort = None
            self.destIf = destIf
            self.destIfPort = None
            self.src_interface_status = 'down'
            self.dest_interface_status = 'down'
            
            self.labelSrcIf = None
            self.labelDstIf = None
            self.src_xpos = None
            self.src_ypos = None
            self.dst_xpos = None
            self.dst_ypos = None

            # capture feature variables
            self.capturing = False
            self.capfile = None
            self.captureInfo = None

            # create a unique ID
            self.id = globals.GApp.topology.link_baseid
            globals.GApp.topology.link_baseid += 1

            # Set default tooltip
            #self.setCustomToolTip()

            # record the edge into the nodes
            self.source.addEdge(self)
            self.dest.addEdge(self)

            # set item focusable
            self.setFlag(self.ItemIsFocusable)
   
        else:
            src_rect = self.source.boundingRect()
            self.src = self.mapFromItem(self.source, src_rect.width() / 2.0, src_rect.height() / 2.0)
            self.dst = self.dest
            
            
        # color
        #
        #self.setBrush(QtGui.QBrush(Qt.yellow))
        
    def adjust(self):
        """ Compute the source point and destination point
            Must be called when overloaded
        """

        self.prepareGeometryChange()
        src_rect = self.source.boundingRect()
        self.src = self.mapFromItem(self.source, src_rect.width() / 2.0, src_rect.height() / 2.0)

        # if source point is not a mouse point
        if not self.fake:

            dst_rect = self.dest.boundingRect()
            self.dst = self.mapFromItem(self.dest, dst_rect.width() / 2.0, dst_rect.height() / 2.0)

        # compute vectors
        self.dx = self.dst.x() - self.src.x()
        self.dy = self.dst.y() - self.src.y()

        # compute the length of the line
        self.length = math.sqrt(self.dx * self.dx + self.dy * self.dy)
        self.draw = True
        
        if self.labelDstIf:
            self.labelSrcIf.setPos(self.src + self.edgeOffset)
            self.labelDstIf.setPos(self.dst - self.edgeOffset)        
        
        
        
      
    
    def setMousePoint(self,  scene_point):
        self.dst = scene_point
        self.adjust()
        self.update()
        
    def updateLabel(self):
        self.labelSrcIf = QtGui.QGraphicsTextItem(self.srcIf,  self)
        self.labelSrcIf.setFont(QtGui.QFont("TypeWriter",  8,  QtGui.QFont.Bold))
        self.labelSrcIf.setDefaultTextColor(QtGui.QColor(globals.IfnameColor))
        self.labelSrcIf.setFlag(self.labelSrcIf.ItemIsMovable)
        self.labelSrcIf.setZValue(2)
        self.labelSrcIf.setPos(self.src + self.edgeOffset)
        
        self.labelDstIf = QtGui.QGraphicsTextItem(self.destIf,  self)
        self.labelDstIf.setFont(QtGui.QFont("TypeWriter",  8,  QtGui.QFont.Bold))
        self.labelDstIf.setDefaultTextColor(QtGui.QColor(globals.IfnameColor))
        self.labelDstIf.setFlag(self.labelDstIf.ItemIsMovable)
        self.labelDstIf.setZValue(2)
        self.labelDstIf.setPos(self.dst - self.edgeOffset)
        
        globals.GApp.topology.addItem(self.labelSrcIf)
        globals.GApp.topology.addItem(self.labelDstIf)
      
    def getTypeName(self):
        if self.type == globals.Enum.LinkType.Ethernet:
            typeName = "E"
        elif self.type == globals.Enum.LinkType.FastEthernet:
            typeName = "FE"
        elif self.type == globals.Enum.LinkType.GigaEthernet:
            typeName = "GE"
        elif self.type == globals.Enum.LinkType.Serial:
            typeName = "Serial"
        elif self.type == globals.Enum.LinkType.ATM:
            typeName = "ATM"
        elif self.type == globals.Enum.LinkType.POS:
            typeName = "POS"
        elif self.type == globals.Enum.LinkType.Manual:
            typeName = "Manual"
        else:
            typeName = "Ethernet"
        
        return typeName
        
    def getTypeName2(self,  str):
        if str == "E":
            self.typeName2 = "Ethernet"
        elif str == "FE":
            self.typeName2 = "FastEthernet"
        elif str == "GE":
            self.typeName2 = "GigaEthernet"
        else:
            msg = "[getTypeName2] undefined parameter (%s)" % str
            debug(msg)
        return self.typeName2

    def getSrcSlotNPort(self):
        """ return src Slot and Port Number
        return (s, n)
        """
        return self.__parseIfName(self.srcIf)
    
    def getDstSlotNPort(self):
        """ return dst Slot and Port Number
        return (s,n) 
        """
        return self.__parseIfName(self.destIf)
        
    def __parseIfName(self,  str):
        """ parse string
        ex) FE 1/2 --> (1,2)
        ex) fxp 2 --> (2,0)
        """
        index = str.split(" ")
        sp = index[1].split("/")
        slot = int(sp[0])
        port = 0
        if len(sp) == 2:
            port = int(sp[1])
        
        msg = "input:(%s) return (%s,%s)" % (str,  slot,  port)
        debug(msg)
        return (slot,  port)
    
    # XML
    def getXML(self):
        # <Link type="FastEthernet" nodeA='RouterA' nodeB='RouterB' nodeAIF='fxp0' nodeBIF='FastEthernet0/0' delay='1ms'/>
        link = self.xml.createElement("Link")
        link.setAttribute("type",  self.getTypeName2(self.typeName))
        link.setAttribute("nodeA",  self.source.hostname)
        link.setAttribute("nodeB",  self.dest.hostname)
        link.setAttribute("nodeAIF", self.srcIf)
        link.setAttribute("nodeBIF", self.destIf)
        link.setAttribute("delay",  self.delay)
        
        return link
    
    #####################
    # Events
    #####################
    def hoverEnterEvent(self,  event):
        # mouse is over link
        # change to bold link
        info = "%s <--> %s" % (self.srcIf,  self.destIf)
        self.setToolTip(info)
        
        
    def hoverLeaveEvent(self,  event):
        # mouse is out link
        # change to common link
        self.penWidth = 2.0
